-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove ActiveSupport from runtime #16463
Conversation
b76155c
to
4267a7a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far!
3dfce75
to
07f98a9
Compare
@@ -6,6 +6,7 @@ | |||
require "utils/user" | |||
require "cask/artifact/abstract_artifact" | |||
require "cask/pkg" | |||
require "extend/hash/keys" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I scoped these to the files that used them, rather than in global
@is_dev_cmd = cmd_location.absolute_path.start_with?(Commands::HOMEBREW_DEV_CMD_PATH) | ||
end.fetch(1) | ||
@command_name = T.must(cmd_location.label).chomp("_args").tr("_", "-") | ||
@is_dev_cmd = T.must(cmd_location.absolute_path).start_with?(Commands::HOMEBREW_DEV_CMD_PATH) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor changes that are required when adding sig
s to vendored methods
# typed: strict | ||
|
||
class Array | ||
sig { returns(T.nilable(Elem)) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elem
is an upstream RBI creation that isn't available at runtime, so these need to be in RBI files. (And similarly for Enumerable::Enum
, Hash::K
, Hash::V
, etc. below…)
end | ||
|
||
class Hash | ||
sig { returns(T::Hash[Hash::K, Hash::V]) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to use a runtime sig
with returns(T.self_type)
, but that's a bug: sorbet/sorbet#7586
end | ||
end | ||
hash | ||
end | ||
end | ||
|
||
class Module |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is sourced from the current upstream implementation
|
||
require "singleton" | ||
|
||
module Singleton |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another upstream addition
^https?:// | ||
(?:(?:[^/]+?\.)*gnu\.org/(?:gnu|software)/(?<project_name>[^/]+)/ | ||
|(?<project_name>[^/]+)\.gnu\.org/?$) | ||
}ix.freeze | ||
}ix.freeze, Regexp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strict typing and this change somehow resolve a spurious type error on line 42 ¯\(ツ)/¯
@@ -2,6 +2,7 @@ | |||
# frozen_string_literal: true | |||
|
|||
require "sorbet-runtime" | |||
require "extend/module" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly unrelated, but as of this change, the extension only extends Module
to include T::Sig
, so IMO it makes the most sense to live here rather than global
.
components[:query] = URI.decode_www_form(uri_query).map(&:second) | ||
components[:query] = URI.decode_www_form(uri_query).map { _2 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't seen this pattern in the wild. Very cool!
Co-authored-by: Mike McQuaid <[email protected]>
07f98a9
to
4cd6c51
Compare
Ready for review |
each { |elem| result[yield(elem)] = elem } | ||
result | ||
else | ||
T.unsafe(self).to_enum(:index_by) { T.unsafe(self).size if respond_to?(:size) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really ugly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm honestly not entirely sure what's going on here. There's only two usages of index_by
so if we're wanting to keep it then we don't really need to keep the nil-block case which has a behaviour that's undocumented anyway.
The whole thing can probably be simpified to each_with_object({}) { |elem, hash| hash[yield(elem)] = elem }
, or replace the two usages with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that index_by
can probably be removed entirely and this code inlined given there's only two usages.
Looks ok, though some cleanup would be nice afterwards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @dduugg! As this is a bit of a handful to review, I think it's probably worth merging soon (or as-is, will leave that up-to-you).
I think index_by
and perhaps deep_dup
could be dropped but that could be a follow-up PR if necessary.
each { |elem| result[yield(elem)] = elem } | ||
result | ||
else | ||
T.unsafe(self).to_enum(:index_by) { T.unsafe(self).size if respond_to?(:size) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that index_by
can probably be removed entirely and this code inlined given there's only two usages.
@@ -12,6 +13,7 @@ class Object | |||
# | |||
# object.instance_variable_defined?(:@a) # => false | |||
# dup.instance_variable_defined?(:@a) # => true | |||
sig { returns(T.self_type) } | |||
def deep_dup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @Bo98 mentioned: I think we can drop this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naïvely swapping out deep_dup
for dup
in abstract_artifact
leads to test failures in test/cask/cask_spec.rb
– could i trouble someone with more context to take a deeper (pun intended) look into this one?
I believe that I've addressed all the feedback except for |
ccb1c03
to
7036c9d
Compare
7036c9d
to
e574904
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again @dduugg!
brew style
with your changes locally?brew typecheck
with your changes locally?brew tests
with your changes locally?Relates to #16190
Removes ActiveSupport from the brew runtime (it will still exist as a transitive dependency of rubocop-rails, for now).
I recommend to squash commits on merge (or I can force-push a squashed commit, not sure what the merge options are here).
I've used just the parts of the ActiveSupport files that we use, with some light modifications (including adding type signatures, and pulling in upstream changes, for which I've added comments). Another option could be to just vendor the existing dependencies, as we do with
mechanize
. However, ActiveSupport sometimes undergoes refactors and dependency changes, which might be a headache to keep up with (for instance, this refactor of Hash#deep_merge! to introduce anotherDeepMergeable
module).I haven't added new tests for this functionality, but don't want to dismiss their importance/value (rails uses a different framework, preventing this from being a simple c/p operation). Looks like there a just few spots without coverage though (including some error paths that may be hard to plausibly simulate). LMK if more are desirable.